import React, { useEffect, useState } from 'react';
import { Spin, TreeSelect } from 'antd';
import { hasIn, isObject, size, uniqBy } from 'lodash';

import { toArray } from '@/utils/utils';
import styles from '@/components/OrganizationSelect/index.less'
import useOrganizationList from './useOrganizationList';

/**
 *@description 获取树选中所有子孙值
 * @param {Object} datasource 选中的树节点
 */
const getChildrenData = datasource => {
    if (size(datasource) > 0) {
        const tempArr = [];
        // 递归获取数据
        const deepFn = node => {
            let obj = node;
            if (hasIn(obj, 'props')) {
                obj = obj.props;
            }
            tempArr.push({ value: obj?.value, label: obj?.label || obj?.title });
            if (Array.isArray(obj.children)) {
                obj.children.forEach(item => {
                    deepFn(item);
                });
            }
        };
        deepFn(datasource);
        return tempArr;
    }
    return [];
};

/**
 *
 * @description 双组织机构下拉：默认情况下为行政机构-对应companyCode
 * @param {Boolean} isFunctional 变更为职能机构/组织机构-对应departmentCode，默认false
 * @param {Object} extraQuery 扩展其他查询参数
 * @param {Boolean} treeCheckable 显示 checkbox，组件变为多选
 * @param {Boolean} isNeedPermission 是否需要权限，默认不需要
 * @param {Boolean} isStrictly 替换treeCheckStrictly属性，父子节点选中状态不再关联，默认输出是对象数组，可通过strictlyOutType配置输出类型，回填的时候可以是字符串数组
 * @param {Boolean} strictlyOutType 启用isStrictly后输出的值类型，有string和object可选，默认string
 * @param {Boolean} unLoading 可以不显示数据加载中的loading状态
 * */
const AllOrganizationSelect = React.forwardRef(
    (
        {
            value,
            onChange,
            labelInValue = false,
            isFunctional = false,
            isNeedPermission = false,
            isStrictly = false,
            unLoading = false,
            strictlyOutType = 'string',
            extraQuery,
            dataSource,
            cacheKey,
            ...rest
        },
        ref
    ) => {
        const [loading, data] = useOrganizationList(dataSource, cacheKey);
        const [treeData, setTreeData] = useState([]);
        const [selectValue, setSelectValue] = useState();
        const [expandedKeys, setExpandedKeys] = useState([]);
        const { treeCheckable } = rest;

        // 处理isStrictly开启下返回的数据结构
        useEffect(() => {
            let tempValue = value;
            let tempExpandedKeys = toArray(value);
            if (size(value) > 0) {
                if ((isStrictly === true || labelInValue === true) && treeCheckable === true) {
                    if (Array.isArray(value)) {
                        tempValue = value.map(item => {
                            if (isObject(item)) {
                                return item;
                            }
                            return { label: '', value: item };
                        });
                        tempExpandedKeys = value.map(item => {
                            if (isObject(item)) {
                                return item.value;
                            }
                            return item;
                        });
                    } else {
                        tempValue = [{ label: '', value }];
                        tempExpandedKeys = [value];
                    }
                }
            }
            setExpandedKeys(tempExpandedKeys);
            setSelectValue(size(tempValue) > 0 ? tempValue : undefined);
        }, [isStrictly, labelInValue, treeCheckable, value]);

        const handleChange = (changeValue, label, extra) => {
            let tempArr = changeValue;
            // isStrictly状态下要选择子孙节点
            if (isStrictly === true && extra.checked === true) {
                tempArr = getChildrenData(extra.triggerNode.props);
                tempArr = uniqBy([...changeValue, ...tempArr], 'value');
            }

            if (typeof strictlyOutType === 'string' && strictlyOutType === 'string' && Array.isArray(tempArr)) {
                tempArr = tempArr.map(item => {
                    if (isObject(item)) {
                        return item.value;
                    }
                    return item;
                });
            }
            if (onChange) {
                onChange(tempArr, label);
            }
        };

        useEffect(() => {
            const tempData = data;
            if (size(tempData)) {
                // 树数据转换
                const preprocessDataItem = array =>
                    array?.map(item => {
                        const obj = item;
                        // 如果没有数据权限，不可选择
                        if (obj.organizationPermissions === 0 && isNeedPermission === true) {
                            obj.checkable = false;
                            obj.selectable = false;
                        }
                        if (obj?.children?.length) {
                            obj.children = preprocessDataItem(obj.children);
                        }
                        if (isFunctional && (obj.organizationType === 1 || obj.organizationType === 2)) {
                            // 组织机构下不能选择集团和公司
                            obj.checkable = false;
                            obj.selectable = false;
                        }
                        if (!isFunctional && obj.organizationType === 3) {
                            // 行政机构下不能选择部门
                            obj.checkable = false;
                            obj.selectable = false;
                        }
                        return {
                            ...obj,
                            value: obj.organizationCode,
                            title: <div>
                                {obj.organizationName}
                                <span style={{ color: 'red' }}>{obj?.deleteFlag === 1 ? '（已删除）' : ''}</span>
                            </div>,
                            filterProp: obj.organizationName,
                            key: obj.organizationCode
                        };
                    });
                const arr = preprocessDataItem(tempData);
                setTreeData(arr);
            }
        }, [data, isFunctional, isNeedPermission]);

        return (
            <Spin spinning={unLoading === true ? false : loading} wrapperClassName={styles.orgSelectSpingWrapper}>
                <TreeSelect
                    ref={ref}
                    showSearch
                    allowClear
                    placeholder={isFunctional ? '请选择组织机构' : '请选择行政机构'}
                    treeData={treeData}
                    value={selectValue}
                    onChange={handleChange}
                    treeDefaultExpandAll
                    treeNodeFilterProp="filterProp"
                    style={{ minWidth: '180px' }}
                    showCheckedStrategy="SHOW_ALL"
                    treeDefaultExpandedKeys={expandedKeys}
                    dropdownStyle={{ maxHeight: 350, overflow: 'auto' }}
                    getPopupContainer={triggerNode => triggerNode.parentElement}
                    {...rest}
                    labelInValue={labelInValue}
                    treeCheckStrictly={isStrictly}
                />
            </Spin>
        );
    }
);

export default AllOrganizationSelect;
